﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Xml.Linq;
using PowerPoint = Microsoft.Office.Interop.PowerPoint;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Interop.PowerPoint;
using Microsoft.Office.Tools.Ribbon;
using System.IO;

namespace PowerWaveAddin
{
	public partial class ThisAddIn
	{
		/// <summary>
		/// Whether remote or local service should be used.
		/// This is all you need to change to make the switch now.
		/// </summary>
		internal static ExecutionMode OperationMode = ExecutionMode.HostedService;

		private PowerPoint.EApplication_SlideShowNextSlideEventHandler slideChangeListener;

		public static SimplePostHelper postHelper;

		internal static UploadCode currentUploadState = UploadCode.UNPUBLISHED;

		internal PresentationManager presentationManager = new PresentationManager();

        private SlideSyncQueue ssq;

		private void ThisAddIn_Startup(object sender, System.EventArgs e)
		{
			this.Application.SlideShowBegin += new Microsoft.Office.Interop.PowerPoint.EApplication_SlideShowBeginEventHandler(Application_SlideShowBegin);
			this.Application.SlideShowEnd += new Microsoft.Office.Interop.PowerPoint.EApplication_SlideShowEndEventHandler(Application_SlideShowEnd);
			UploadForm.Instance.UploadComplete += new UploadForm.UploadCompleteHandler(OnUploadCompleted);
            
            this.ssq = new SlideSyncQueue();
		}

		private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
		{
		}

		#region VSTO generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InternalStartup()
		{
			this.Startup += new System.EventHandler(ThisAddIn_Startup);
			this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
		}

		#endregion

		void Application_SlideShowBegin(Microsoft.Office.Interop.PowerPoint.SlideShowWindow Wn)
		{
			this.slideChangeListener = new EApplication_SlideShowNextSlideEventHandler(Application_SlideShowNextSlide);
			this.Application.SlideShowNextSlide += this.slideChangeListener;
			this.syncToSlide(Wn.View.Slide.SlideNumber);
		}

		void Application_SlideShowNextSlide(SlideShowWindow Wn)
		{
			this.syncToSlide(Wn.View.Slide.SlideNumber);
		}

		void Application_SlideShowEnd(Microsoft.Office.Interop.PowerPoint.Presentation Pres)
		{
			this.Application.SlideShowNextSlide -= this.slideChangeListener;
		}

		/// <summary>
		/// This method will attempt to save the slides as a set of PNG images in a specified
		/// directory on the local disk.  Then it will call helpers to do the following:
		///     - Upload the images
		///     - Create a new presentation wave
		///     - Add the uploaded images to the wave
		/// </summary>
		/// <param name="pName"></param>
		/// <param name="email"></param>
		/// <param name="buttonEnabledToggler">Delegate to enable/dissable the gui</param>
		/// <returns></returns>
		internal void attemptExport(string pName, string email)
		{
			Presentation pres = this.Application.ActiveWindow.Presentation;
			string dirName = pName;

			PowerWaveRibbon.Instance.ControlTogglerImpl(false);

			//LegacyUploader uploader = new LegacyUploader(buttonEnabledToggler);
			//uploader.ShowStatusForm();
			//uploader.StatusForm.AppendStringToReportDelegateAccessor(
			//    Properties.Resources.PublishingIMagesMessage,
			//    string.Empty);

			// Moving this to a background worker in the uploader
			//pres.SaveCopyAs(
			//    pName,
			//    PpSaveAsFileType.ppSaveAsPNG,
			//    Office.MsoTriState.msoTriStateMixed);

			UploadForm.Instance.ShowAndUpload(dirName, email);

			//uploader.StatusForm.UpdateLastEventStatusDelegateAccessor(Properties.Resources.Done);

			//if (AccountConfigForm.Instance.UseWaveStorage)
			//{
			//  uploader.StartUpload(
			//      pName,
			//      email,
			//      dirName);
			//}
			//else
			//{
			//  uploader.StartScpUpload(
			//      pName,
			//      email,
			//      dirName,
			//      AccountConfigForm.Instance.ConfigurationObject);
			//}
		}

		/// <summary>
		/// Handles the upload complete so that the presentation can be presented
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="args"></param>
		void OnUploadCompleted(object sender, UploadCompleteEventArgs args)
		{
			PowerWaveRibbon.Instance.ControlTogglerImpl(true);
			lock (presentationManager)
			{
                if (args.PresentationKey != null)
                {
				    presentationManager.SetCurrentPresentation(new PresentationInfo()
				    {
					    Key = args.PresentationKey,
					    Name = args.PresentationName
				    });
                }
			}
		}

		/// <summary>
		/// Make the webservice call to sync to a specific slide.
		/// </summary>
		/// <param name="slideNum"></param>
		internal void syncToSlide(int slideNum)
		{
			// decrement the slide number since we use a 1 based index, but google uses a 0 based oindex.
			slideNum -= 1;

			lock (presentationManager)
			{
				PresentationInfo pInfo = this.presentationManager.GetCurrentPresentation();

				if (pInfo == null ||
						String.IsNullOrEmpty(pInfo.Key))
					return;

				IList<KeyValuePair<string, string>> syncFormData = new List<KeyValuePair<string, string>>(3);

				syncFormData.Add(new KeyValuePair<string, string>(FieldNames.Method, MethodFieldValues.Sync));
				syncFormData.Add(new KeyValuePair<string, string>(FieldNames.PresentationKey, pInfo.Key));

				syncFormData.Add(new KeyValuePair<string, string>(FieldNames.SlideIndex, slideNum.ToString()));

				PostHelpers.PresentationPostHelper.ExecutePost(syncFormData);
			}
		}

		internal ICollection<string> GetPresentationListForUser(string userAddress)
		{
			SimplePostHelper postHelper = PostHelpers.PresentationPostHelper;

			NameValueCollection listFormData = new NameValueCollection(2);
			listFormData.Add(FieldNames.Method, MethodFieldValues.List);
			listFormData.Add(FieldNames.Creator, userAddress);

			string jsonResponse = string.Empty;
			lock (postHelper)
			{
				jsonResponse = postHelper.ExecuteGet(
						UrlStrings.PresentationServiceUrl,
						listFormData);
			}

			this.presentationManager.PopulateFromJsonList(jsonResponse);

			return this.presentationManager.GetNameList();
		}
	}
}
